package org.breeze.option.demos.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.breeze.option.demos.entity.databaseEntity.*;
import org.breeze.option.demos.entity.sinoDataEntity.Data;
import org.breeze.option.demos.entity.sinoDataEntity.ResultEntity;
import org.breeze.option.demos.mapper.OptionMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service("optionService")
public class OptionService extends ServiceImpl<OptionMapper, OptionEntity> {
    @Resource
    private CPTotalService cpTotalService;

    public void getNewOption(String option_date, String option_object) {

    }

    /**
     * 定时任务获取数据处理
     * @param msg 定时任务数据
     * @param option_object 合约标的，不同标的存入不同表
     * @author chuyz
     * @date  2024/11/30 22:40
     */
    public void handleSinaData(String msg, String option_object) {

        //具体合约数据和总价数据存入数据库

        ResultEntity result = JSON.parseObject(msg, ResultEntity.class);
        Data data = result.getResult().getData();
        long timeStamp = System.currentTimeMillis();

        System.out.println(data.getInfo());

        //生成认沽认购map
        HashMap<Integer, OptionEntity> callMap = new HashMap<>();
        HashMap<Integer, OptionEntity> putMap = new HashMap<>();

        for(String[] strs: data.getUp()) {
            OptionEntity oe = createEntity(timeStamp, strs, "up");
            callMap.put(oe.getExercisePrice(), oe);
        }
        for(String[] strs: data.getDown()) {
            OptionEntity oe = createEntity(timeStamp, strs, "down");
            putMap.put(oe.getExercisePrice(), oe);
        }
        //生成总价map
        HashMap<Integer, CPTotal> totalMap = new HashMap<>();
        callMap.forEach((key, value) -> {
            OptionEntity oe_put = putMap.get(key);
            CPTotal cpTotal = createCPTotal(oe_put, value, timeStamp);
            totalMap.put(key, cpTotal);
        });
        //存入数据库
        super.insertBatch(new ArrayList<>(callMap.values()));
        super.insertBatch(new ArrayList<>(putMap.values()));
        cpTotalService.insertBatch(new ArrayList<>(totalMap.values()));
        //session获取当前页面的状态，获取当前页面显示的标的物，合约日期
        //向页面推送实时合约具体信息，总价信息（包括总价，总持仓），将两个信息提取，数据组包
        //推送echarts信息，
        //TODO 页面推送流程涉及浏览器请求，需要在浏览器页面初始化请求时，请求参数包含标的物，合约日期，websocket session id信息
        //上述三个信息请求后，存储到spring session中，在定时任务发生时，从spring session中取出，检索出相应标的物，合约日期信息，
        //由websocket session id 发送到对应页面
        // 延后开发


    }

    /**
     * 创建跨式实体，计算跨式价格
     * @param oe_put
     * @param oe_call
     * @param timeStamp
     * @return
     */
    CPTotal createCPTotal(OptionEntity oe_put, OptionEntity oe_call, long timeStamp) {
        CPTotal cpTotal = new CPTotal();
        cpTotal.setUUID(UUID.randomUUID().toString());
        BigDecimal total = BigDecimal.valueOf(oe_put.getNewPrice()).add(BigDecimal.valueOf(oe_call.getNewPrice()));
        cpTotal.setTotal_price(total.doubleValue());
        cpTotal.setTotal_interest(oe_put.getOpenInterest()+ oe_call.getOpenInterest());
        cpTotal.setTimestamp(timeStamp);
        cpTotal.setExercise_price(oe_put.getExercisePrice());
        cpTotal.setC_UUID(oe_call.getUUID());
        cpTotal.setP_UUID(oe_put.getUUID());
        cpTotal.setOption_object(oe_call.getOptionObject());
        cpTotal.setOption_date(oe_call.getOptionDate());
        return cpTotal;
    }

    /**
     * 组装期权合约实体
     * @param timeStamp
     * @param strs
     * @param flag
     * @return
     */
    OptionEntity createEntity(long timeStamp, String[] strs, String flag) {
        //数据为“-” 处理
        for(int i = 0; i < strs.length; i++) {
            if(strs[i].equals("-")) {
                strs[i] = "0";
            }
        }
        OptionEntity oe = new OptionEntity();
        oe.setUUID(UUID.randomUUID().toString());
        oe.setBuyQuantity(Integer.parseInt(strs[0]));
        oe.setBuyPrice(Double.parseDouble(strs[1]));
        oe.setNewPrice(Double.parseDouble(strs[2]));
        oe.setSalePrice(Double.parseDouble(strs[3]));
        oe.setSaleQuantity(Integer.parseInt(strs[4]));
        oe.setOpenInterest(Integer.parseInt(strs[5]));
        oe.setPriceChange(Double.parseDouble(strs[6]));
        if(flag.equals("up")) {
            oe.setExercisePrice(Integer.parseInt(strs[7]));
            oe.setContractName(strs[8]);//io2412P3800
            oe.setCallOrPut("call");
            oe.setOptionDate(strs[8].substring(2,6));
            oe.setOptionObject(strs[8].substring(0,2));
        } else {
            oe.setExercisePrice(Integer.parseInt(strs[7].split("P")[1]));
            oe.setContractName(strs[7]);
            oe.setCallOrPut("put");
            oe.setOptionDate(strs[7].substring(2,6));
            oe.setOptionObject(strs[7].substring(0,2));
        }
        oe.setTimeStamp(timeStamp);
        return oe;
    }
}
